package org.seedltd.upms.controller.wx;

import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.seedltd.base.annotation.IgnoreResponseWrap;
import org.seedltd.core.utils.DateUtils;
import org.seedltd.core.utils.JsonUtils;
import org.seedltd.pay.PayUtils;
import org.seedltd.pay.weChar.WeCharPayService;
import org.seedltd.pay.weChar.WeCharResponse;
import org.seedltd.upms.constant.GlobalConst;
import org.seedltd.upms.enums.OrderStatus;
import org.seedltd.upms.model.detection.entity.DetectionOrder;
import org.seedltd.upms.model.detection.entity.DetectionOrderRefund;
import org.seedltd.upms.service.detection.DetectionOrderRefundService;
import org.seedltd.upms.service.detection.DetectionOrderService;
import org.seedltd.upms.utils.LocalLock;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 *
 * 微信回调
 *
 * @author laizuan
 * @version 1.0
 * @since 2021/8/20 13:58
 */
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/wx/notify")
public class WeCharNotifyController {

    private final WeCharPayService weCharPayService;
    private final DetectionOrderRefundService detectionOrderRefundService;
    private final DetectionOrderService detectionOrderService;

    /**
     * 微信支付通知
     * 
     * @param request
     * @return
     */
    @IgnoreResponseWrap
    @RequestMapping("/pay")
    public WeCharResponse payNotify(HttpServletRequest request) {
        try {
            WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = weCharPayService.parseOrderNotifyV3Result(request);
            WxPayOrderNotifyV3Result.DecryptNotifyResult result = wxPayOrderNotifyV3Result.getResult();
            log.info("##############收到微信支付消息通知： {}", JsonUtils.toJsonString(result));

            String outTradeNo = result.getOutTradeNo();

            try {
                LocalLock.lock(outTradeNo);
                DetectionOrder obj = detectionOrderService.getByOrderNo(outTradeNo);
                if (obj == null) {
                    return WeCharResponse.ok();
                }

                if (obj.getState() < OrderStatus.UN_DELIVER.getValue()) {
                    DetectionOrder update = new DetectionOrder();
                    update.setId(obj.getId());
                    update.setState(OrderStatus.UN_DELIVER.getValue());
                    detectionOrderService.updateById(update);
                }

                if (obj.getVendingMachineId() != null && GlobalConst.PURCHASE_CHANNEL_VM.equals(obj.getChannel())
                    && GlobalConst.NO.equals(obj.getExportFlag())) {
                    detectionOrderService.exportGoods(obj.getId(), false);
                }

            } finally {
                LocalLock.unlock(outTradeNo);
            }
            return WeCharResponse.ok();
        } catch (Exception e) {
            log.error("微信回调结果异常,异常原因：" + e.getMessage(), e);
            return WeCharResponse.error(e.getMessage());
        }
    }

    /**
     * 微信退款通知
     * 
     * @param request
     * @return
     */
    @IgnoreResponseWrap
    @RequestMapping("/refund")
    public WeCharResponse refundNotify(HttpServletRequest request) {
        try {
            WxPayRefundNotifyV3Result notifyResult = weCharPayService.parseRefundNotifyV3Result(request);
            WxPayRefundNotifyV3Result.DecryptNotifyResult result = notifyResult.getResult();
            log.info("$$$$$$$$$$$$$收到微信退款消息通知： {}", JsonUtils.toJsonString(result));

            DetectionOrderRefund orderRefund = detectionOrderRefundService.findByRefundOutId(result.getOutRefundNo());
            String refundStatus = result.getRefundStatus();
            switch (refundStatus) {
                case "SUCCESS":
                    orderRefund.setRefundState("退款成功");
                    break;
                case "CLOSE":
                    orderRefund.setRefundState("退款关闭");
                    break;
                case "ABNORMAL":
                    orderRefund.setRefundState("退款异常。可前往【商户平台—>交易中心】，手动处理此笔退款");
                    break;
            }

            orderRefund.setNotifyTime(DateUtils.now(DateUtils.YYYY_MM_DD_HH_MM_SS));
            orderRefund.setRefundId(result.getRefundId());
            WxPayRefundNotifyV3Result.Amount amount = result.getAmount();
            orderRefund.setPayerRefund(PayUtils.fenToYuan(amount.getPayerRefund()));
            orderRefund.setUserReceivedAccount(result.getUserReceivedAccount());
            orderRefund.setSuccessTime(result.getSuccessTime());
            detectionOrderRefundService.updateById(orderRefund);
            return WeCharResponse.ok();
        } catch (Exception e) {
            log.error("微信回调结果异常,异常原因：" + e.getMessage(), e);
            return WeCharResponse.error(e.getMessage());
        }
    }
}
